using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;

namespace WL.Think.Abp.Permission;

public abstract class GroupPermissionDefinitionProvider<TResource> : PermissionDefinitionProvider
{
    /// <summary>
    /// 分组权限名
    /// </summary>
    protected abstract string Name { get; }

    /// <summary>
    /// 分组权限显示名称
    /// </summary>
    protected abstract string DisplayName { get; }

    /// <summary>
    /// 分组权限
    /// </summary>
    protected PermissionGroupDefinition PermissionGroup { get; private set; } = null!;


    /// <summary>
    /// 定义分组
    /// </summary>
    /// <param name="context"></param>
    public override void Define(IPermissionDefinitionContext context)
    {
        PermissionGroup = context.AddGroup(Name, L(DisplayName ?? ""));
        DefinePermission();
    }

    /// <summary>
    /// 定义权限
    /// </summary>
    protected abstract void DefinePermission();

    /// <summary>
    /// 添加权限
    /// </summary>
    /// <param name="name"></param>
    /// <param name="displayName"></param>
    /// <param name="multiTenancySide"></param>
    /// <param name="isEnabled"></param>
    /// <returns></returns>
    protected PermissionDefinition AddPermission(
        string name,
        string? displayName = null,
        MultiTenancySides multiTenancySide = MultiTenancySides.Both,
        bool isEnabled = true
    )
    {
        return PermissionGroup.AddPermission(name, L(displayName ?? ""), multiTenancySide, isEnabled);
    }

    /// <summary>
    /// 添加子权限
    /// </summary>
    /// <param name="source"></param>
    /// <param name="name"></param>
    /// <param name="displayName"></param>
    /// <param name="multiTenancySide"></param>
    /// <param name="isEnabled"></param>
    /// <returns></returns>
    protected PermissionDefinition AddChild(
        PermissionDefinition source,
        string name,
        string? displayName = null,
        MultiTenancySides multiTenancySide = MultiTenancySides.Both,
        bool isEnabled = true
    )
    {
        return source.AddChild(name, L(displayName ?? ""), multiTenancySide, isEnabled);
    }

    /// <summary>
    /// 本地化解析
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    protected virtual LocalizableString L(string name)
    {
        return LocalizableString.Create<TResource>(name);
    }
}
